/*
 * XComponentVisitor.java
 * 
 * Copyright (c) 2007
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.xfc.testing;

import java.awt.Component;
import java.awt.Container;
import java.awt.Frame;
import java.awt.Window;

// TODO: accept methods for Frame but not for Dialog?
// TODO: component, container, window, dialog, frame, ...

/**
 * 
 * 
 * @author Devon Carew
 */
public abstract class XComponentVisitor
{
	
	/**
	 * Visits all Frames, Windows, Containers, and Components.
	 * 
	 * @param visitor
	 */
	public static Object accept(XComponentVisitor visitor)
	{
		Frame[] frames = Frame.getFrames();
		
		for (int i = 0; i < frames.length && !visitor.isFinished(); i++)
		{
			accept(frames[i], visitor);
		}
		
		return visitor.getResult();
	}
	
	public static Object accept(Frame frame, XComponentVisitor visitor)
	{
		if (!visitor.visit(frame))
			return visitor.getResult();
		
		Window[] windows = frame.getOwnedWindows();
		
		for (int i = 0; i < windows.length && !visitor.isFinished(); i++)
		{
			accept(windows[i], visitor);
		}
		
		return visitor.getResult();
	}
	
	public static Object accept(Window window, XComponentVisitor visitor)
	{
		if (!visitor.visit(window))
			return visitor.getResult();
		
		Component[] components = window.getComponents();
		
		for (int i = 0; i < components.length && !visitor.isFinished(); i++)
		{
			accept(components[i], visitor);
		}
		
		Window[] windows = window.getOwnedWindows();
		
		for (int i = 0; i < windows.length && !visitor.isFinished(); i++)
		{
			accept(windows[i], visitor);
		}		
		
		return visitor.getResult();
	}
	
	public static Object accept(Component component, XComponentVisitor visitor)
	{
		if (component instanceof Container)
		{
			Container container = (Container)component;
			
			if (!visitor.visit(container))
				return visitor.getResult();
			
			Component[] components = container.getComponents();
			
			for (int i = 0; i < components.length && !visitor.isFinished(); i++)
			{
				accept(components[i], visitor);
			}
		}
		else
		{
			visitor.visit(component);
		}
		
		return visitor.getResult();
	}
	
	private Object 	result;
	private boolean finished;
	
	protected boolean visit(Frame frame)
	{
		return true;
	}
	
	protected boolean visit(Window window)
	{
		return true;
	}
	
	protected boolean visit(Container container)
	{
		return true;
	}
	
	protected boolean visit(Component component)
	{
		return true;
	}
	
	public Object getResult()
	{
		return result;
	}
	
	public void setResult(Object result)
	{
		this.result = result;
	}

	public boolean isFinished()
	{
		return finished;
	}
	
	public void setFinished(boolean finished)
	{
		this.finished = finished;
	}

}
